﻿using System;
using System.ComponentModel;
using System.Timers;
using Devv.Core.Utils;
using Devv.FreshTracker.Entity;

namespace Devv.FreshTracker
{
	public class AutoTracking
	{
		#region Events

		public delegate void TimerEventHandler(ref String currentWindow);
		public static event TimerEventHandler OnAutoTimerTick;

		#endregion

		#region Internal Properties

		private static DateTime LastValidWindowDate { get; set; }
		private static Timer Timer { get; set; }

		#endregion

		#region Public Properties

		public static SessionCollection Sessions { get; set; }

		public static Boolean HasSessionsToUpload
		{
			get
			{
				if (Sessions == null || Sessions.Count < 1)
				{
					return false;
				}

				foreach (Session s in Sessions)
				{
					if (s.HasMinimumTime)
					{
						return true;
					}
				}

				return false;
			}
		}

		#endregion

		#region Load and thread safety

		public static void Load()
		{
			Timer = new Timer { Interval = 1000, Enabled = false };
			Timer.Elapsed += Timer_Elapsed;

			Sessions = new SessionCollection();
		}

		public static void ThreadSync(ISynchronizeInvoke thread)
		{
			Timer.SynchronizingObject = thread;
		}

		#endregion

		#region Tracking

		public static void Start()
		{
			if (!Timer.Enabled)
			{
				Maintenance.Log("Auto tracking started.");

				Timer.Start();
			}
		}

		public static void Stop()
		{
			Maintenance.Log("Auto tracking stopped.");

			Timer.Stop();
		}

		private static void Timer_Elapsed(Object sender, ElapsedEventArgs e)
		{
			String currentWindow = String.Empty;
			OnAutoTimerTick(ref currentWindow);

			if (String.IsNullOrEmpty(currentWindow))
			{
				if (LastValidWindowDate.Year < 2000)
				{
					LastValidWindowDate = DateTime.Now;
				}
				else if (LastValidWindowDate.AddMinutes(1) < DateTime.Now)
				{
					return;
				}

				currentWindow = LastWindow.Title;
			}
			else
			{
				LastValidWindowDate = DateTime.Now;
			}

			if (String.IsNullOrEmpty(currentWindow))
			{
				return;
			}

			for (Int32 i = 0; i < LocalCache.Rules.Count; i++)
			{
				Rule r = LocalCache.Rules[i];

				if (currentWindow.ToLower().Contains(r.WindowTitle.ToLower()) || RegexUtil.Test(currentWindow, r.WindowTitle))
				{
					Session s = Sessions.Find(r.Task);

					if (s != null)
					{
						s.TempSeconds++;
					}
					else
					{
						s = new Session();

						s.Date = DateTime.Now;
						s.Task = r.Task;
						s.TempSeconds = 1;
						s.Hours = 0;

						Sessions.Add(s);

						Maintenance.Log("Started tracking time based on rule " + r + ".");
					}

					LastWindow.Title = currentWindow;
					LastWindow.AppliedRule = r;
				}
			}
		}

		#endregion

		#region Save

		public static void Save()
		{
			Maintenance.Log("Saving auto tracking.");

			foreach (Session s in Sessions)
			{
				LocalCache.UploadSession(s);
			}
		}

		#endregion

		#region Last window object

		class LastWindow
		{
			public static String Title { get; set; }
			public static Rule AppliedRule { get; set; }
		}

		#endregion
	}
}